//
//  OpenSDK_SlideView.m
//  code
//
//  Created by 涂俊 on 2018/8/27.
//  Copyright © 2018年 Wicky. All rights reserved.
//

#import "OpenSDK_SlideView.h"
#import "UIBezierPath+DWPathUtils.h"
#import "UIImage+DWImageUtils.h"

@interface OpenSDK_SlideView()

@property (nonatomic ,strong) UIView * sliderBgView;

@property (nonatomic ,strong) UILabel * sliderTextView;

@property (nonatomic ,strong) UILabel * successTextView;

// 异步下载图片的小菊花
@property (nonatomic, strong) UIActivityIndicatorView * activityIndicator;

@property int errorCount;// 验证失败错误计数

// 展示/隐藏回调（只有在displayHide为true时才回调）
@property (nonatomic ,copy) SlideView_DisplayHideBlock displayHideCallback;

@end

@implementation OpenSDK_SlideView

{
    BOOL displayHide;// 是否隐藏模式
    UInt64 startTime;//开始拖动的时间戳，毫秒
    BOOL dragVerify;// 记录一次完整的拖动
    BOOL validDrag;// 记录有效的拖动
}

static CGFloat trackHeight = 40;
static CGFloat trackPadding = 10;
static NSTimeInterval resetDelay = 0.2;//恢复滑块的动画延迟，单位：秒

- (instancetype)initWithFrame:(CGRect)frame {
    if (self = [super initWithFrame:frame]) {
        [self initView];
    }
    return self;
}

- (instancetype)initWithCoder:(NSCoder *)aDecoder {
    if (self = [super initWithCoder:aDecoder]) {
        [self initView];
    }
    return self;
}

-(void) initView {
    
    [self setBackgroundColor:[UIColor clearColor]];
    
    // slider横条
    _sliderBgView = [[UIView alloc] init];
    [_sliderBgView setUserInteractionEnabled:YES];
    [_sliderBgView setTranslatesAutoresizingMaskIntoConstraints:NO];
    [_sliderBgView setBackgroundColor:[UIColor whiteColor]];
    [_sliderBgView.layer setCornerRadius:trackHeight/2];
    [_sliderBgView.layer setBorderWidth:1.0];
    [_sliderBgView.layer setBorderColor:[UIColor lightGrayColor].CGColor];
    [self addSubview:_sliderBgView];
    [self addConstraint:[NSLayoutConstraint constraintWithItem:self.sliderBgView attribute:NSLayoutAttributeLeading relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeLeading multiplier:1.0 constant:0]];
    [self addConstraint:[NSLayoutConstraint constraintWithItem:self.sliderBgView attribute:NSLayoutAttributeTrailing relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeTrailing multiplier:1.0 constant:0]];
    [self addConstraint:[NSLayoutConstraint constraintWithItem:self.sliderBgView attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeHeight multiplier:1.0 constant:trackHeight]];
    [self addConstraint:[NSLayoutConstraint constraintWithItem:self.sliderBgView attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeBottom multiplier:1.0 constant:0]];
    
    // 提示文字
    _sliderTextView = [[UILabel alloc] init];
    [_sliderTextView setTranslatesAutoresizingMaskIntoConstraints:NO];
    _sliderTextView.font = [UIFont systemFontOfSize: 12.0];
    [_sliderTextView setTextColor:[UIColor lightGrayColor]];
    [_sliderBgView addSubview:_sliderTextView];
    [self addConstraint:[NSLayoutConstraint constraintWithItem:self.sliderTextView attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:_sliderBgView attribute:NSLayoutAttributeCenterX multiplier:1.0 constant:20]];
    [self addConstraint:[NSLayoutConstraint constraintWithItem:self.sliderTextView attribute:NSLayoutAttributeCenterY relatedBy:NSLayoutRelationEqual toItem:_sliderBgView attribute:NSLayoutAttributeCenterY multiplier:1.0 constant:0]];
    
    // 成功文字
    _successTextView = [[UILabel alloc] init];
    [_successTextView setTranslatesAutoresizingMaskIntoConstraints:NO];
    _successTextView.font = [UIFont systemFontOfSize: 12.0];
    [_successTextView setTextColor:[UIColor greenColor]];
    _successTextView.hidden = YES;
    [_sliderBgView addSubview:_successTextView];
    [self addConstraint:[NSLayoutConstraint constraintWithItem:self.successTextView attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:_sliderBgView attribute:NSLayoutAttributeCenterX multiplier:1.0 constant:0]];
    [self addConstraint:[NSLayoutConstraint constraintWithItem:self.successTextView attribute:NSLayoutAttributeCenterY relatedBy:NSLayoutRelationEqual toItem:_sliderBgView attribute:NSLayoutAttributeCenterY multiplier:1.0 constant:0]];
    
    // slider控件
    _slider = [[UISlider alloc] init];
    [_slider setTranslatesAutoresizingMaskIntoConstraints:NO];
    [_slider setMinimumValue:0.0];
    [_slider setMaximumValue:1.0];
    [_slider setMaximumTrackTintColor:[UIColor clearColor]];
    [_slider setMinimumTrackTintColor:[UIColor clearColor]];
    self.dragable = NO;// 等到真正加载了滑块图片，才能开始滑动拼图
    [_sliderBgView addSubview:_slider];
    [self addConstraint:[NSLayoutConstraint constraintWithItem:self.slider attribute:NSLayoutAttributeLeading relatedBy:NSLayoutRelationEqual toItem:_sliderBgView attribute:NSLayoutAttributeLeading multiplier:1.0 constant:0]];
    [self addConstraint:[NSLayoutConstraint constraintWithItem:self.slider attribute:NSLayoutAttributeTrailing relatedBy:NSLayoutRelationEqual toItem:_sliderBgView attribute:NSLayoutAttributeTrailing multiplier:1.0 constant:0]];
    [self addConstraint:[NSLayoutConstraint constraintWithItem:self.slider attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:_sliderBgView attribute:NSLayoutAttributeTop multiplier:1.0 constant:0]];
    [self addConstraint:[NSLayoutConstraint constraintWithItem:self.slider attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:_sliderBgView attribute:NSLayoutAttributeBottom multiplier:1.0 constant:0]];
    
    // captchaView在slider上部
    _captchaView = [[DWSlideCaptchaView alloc] init];
    [_captchaView setUserInteractionEnabled:YES];
    [_captchaView setTranslatesAutoresizingMaskIntoConstraints:NO];
    _captchaView.delegate = self;
    _captchaView.bgImageRadius = 8;
    [self addSubview:_captchaView];
    [self addConstraint:[NSLayoutConstraint constraintWithItem:self.captchaView attribute:NSLayoutAttributeLeading relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeLeading multiplier:1.0 constant:0]];
    [self addConstraint:[NSLayoutConstraint constraintWithItem:self.captchaView attribute:NSLayoutAttributeTrailing relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeTrailing multiplier:1.0 constant:0]];
    [self addConstraint:[NSLayoutConstraint constraintWithItem:self.captchaView attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeTop multiplier:1.0 constant:0]];
    [self addConstraint:[NSLayoutConstraint constraintWithItem:self.captchaView attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:_sliderBgView attribute:NSLayoutAttributeTop multiplier:1.0 constant:-trackPadding]];
    // 添加点击事件
    UITapGestureRecognizer *tapGR=[[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(didClickCaptherView:)];
    [_captchaView addGestureRecognizer:tapGR];
    
    // 菊花在captchaView中间
    self.activityIndicator = [[UIActivityIndicatorView alloc]initWithActivityIndicatorStyle:(UIActivityIndicatorViewStyleGray)];
    [self.activityIndicator setTranslatesAutoresizingMaskIntoConstraints:NO];
    self.activityIndicator.frame= CGRectMake(100, 100, 100, 100);
    self.activityIndicator.hidesWhenStopped = YES;
    [_captchaView addSubview:self.activityIndicator];
    [self addConstraint:[NSLayoutConstraint constraintWithItem:self.activityIndicator attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:_captchaView attribute:NSLayoutAttributeCenterX multiplier:1.0 constant:0]];
    [self addConstraint:[NSLayoutConstraint constraintWithItem:self.activityIndicator attribute:NSLayoutAttributeCenterY relatedBy:NSLayoutRelationEqual toItem:_captchaView attribute:NSLayoutAttributeCenterY multiplier:1.0 constant:0]];
    
    ///为了获取slider结束拖动使用KVO
    [self addObserver:self forKeyPath:@"slider.tracking" options:(NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld) context:nil];
    
    ///为了改变验证视图的时使用通知观察slider的数值
    [self.slider addTarget:self action:@selector(sliderValueChange) forControlEvents:(UIControlEventValueChanged)];
}


#pragma mark ----- DWSlideCaptchaView点击隐藏
- (void)didClickCaptherView:(id)sender {
    if (displayHide) {
        // 只有隐藏模式下，点击图片才会隐藏
        [self hideImageWithAnimation:YES];
    }
}


#pragma mark ----- slider控件，滑动监听
-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context {
    if ([keyPath isEqualToString:@"slider.tracking"]) {
        //        NSLog(@"observeValueForKeyPath,old=%d,new=%d,validDrag=%hhd", [change[@"old"] integerValue], [change[@"new"] integerValue], validDrag);
        if ([change[@"new"] integerValue] == 1 && [change[@"old"] integerValue] == 0) {
            ///silder开始拖动
            dragVerify = NO;
            // 记录拖动开始时间
            startTime = [[NSDate date] timeIntervalSince1970] * 1000;
            // 隐藏模式下，显示图片
            if (displayHide) {
                [self showImageWithAnimation:YES];
            }
            // 该次拖动是否有效，由回调的返回值决定
            if (self.indentifyBegin) {
                validDrag = self.indentifyBegin(self);
            } else {
                validDrag = YES;
            }
            validDrag = self.dragable & validDrag;
        } else if ([change[@"new"] integerValue] == 0) {
            if (dragVerify) {
                return;
            }
            // silder结束拖动
            dragVerify = YES;
            if (!validDrag) {
                NSLog(@"图片未加载完，不响应滑动");
                [self resetSlideValue:0];
                return;
            }
            // 开始验证
            if (!self.captchaView.isSuccessed) {
                [self.captchaView indentifyWithAnimated:YES result:^(BOOL success) {
                    _isSuccess = success;
                    if (!success) {
                        // 验证失败，归位
                        [self resetSlideValue:resetDelay];
                        // 如果没设置错误阈值，则只更换拼图
                        if (self.errorResetCount == 0) {
                            [self.captchaView reset];
                        }
                        // 如果设置了错误阈值，则根据当前错误次数，
                        else {
                            self.errorCount++;
                            if (self.errorCount < self.errorResetCount) {
                                // 错误小于指定阈值，更换拼图
                                [self.captchaView reset];
                            } else {
                                // 错误达到指定阈值，加载新图片，错误次数归零
                                self.errorCount = 0;
                                if (self.loadNewImage) {
                                    self.loadNewImage(self);
                                } else {
                                    // 没有实现加载新图片的回调，更换拼图
                                    [self.captchaView reset];
                                }
                            }
                        }
                    } else {
                        // 计算拖动耗时
                        UInt64 endTime = [[NSDate date] timeIntervalSince1970] * 1000;
                        UInt64 costTime = endTime - startTime;
                        if (costTime < 1000) {
                            NSLog(@"验证成功，耗时小于1秒");
                        } else {
                            double costSeconds = costTime / 1000.0;
                            NSLog(@"验证成功，耗时%.1f秒", costSeconds);
                        }
                        // 验证成功
                        [self resetSlideValue:0];
                        self.slider.enabled = NO;
                        self.slider.hidden = YES;
                        self.successTextView.hidden = NO;
                        self.sliderTextView.hidden = YES;
                        // 隐藏模式下，隐藏图片
                        if (displayHide) {
                            [self hideImageWithAnimation:YES];
                        }
                    }
                    if (self.indentifyCompletion) {
                        self.indentifyCompletion(self, success);
                    }
                    validDrag = NO;
                }];
            }
        }
    }
}

#pragma mark ----- uislide的value归零
-(void) resetSlideValue:(NSTimeInterval) delay {
    dispatch_async(dispatch_get_main_queue(), ^{
        [UIView animateWithDuration:0.5
                              delay:delay
                            options:(UIViewAnimationOptionCurveEaseInOut | UIViewAnimationOptionTransitionNone)
                         animations:^{
                             [self.slider setValue:0 animated:YES];
                         }
                         completion:nil];
    });
}



#pragma mark ----- uislide的value变化的回调
-(void) sliderValueChange {
    if (!self.captchaView.isIndentified && validDrag) {
        [self.captchaView setValue:self.slider.value animated:NO];
    }
}

#pragma mark ----- 图片拼图移动结束的回调
-(void) dw_CaptchaView:(DWSlideCaptchaView *)captchaView animationCompletionWithSuccess:(BOOL)success {
    if (!success) {
        [self.captchaView setValue:0 animated:YES];
    }
}

-(void) dealloc {
    [self removeObserver:self forKeyPath:@"slider.tracking"];
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}

#pragma mark ----- 显示图片
-(void) showImageWithAnimation:(BOOL) animate {
    if (self.displayHideCallback) {
        self.displayHideCallback(YES);
    }
    if (animate) {
        [UIView animateWithDuration:0.5
                         animations:^{
                             self.captchaView.alpha = 1.0;
                         }];
    } else {
        self.captchaView.alpha = 1.0;
    }
}

#pragma mark ----- 隐藏图片
-(void) hideImageWithAnimation:(BOOL) animate {
    if (animate) {
        [UIView animateWithDuration:0.5
                         animations:^{
                             self.captchaView.alpha = 0;
                         }
                         completion:^(BOOL finished) {
                             if (self.displayHideCallback) {
                                 self.displayHideCallback(NO);
                             }
                         }];
    } else {
        self.captchaView.alpha = 0;
        if (self.displayHideCallback) {
            self.displayHideCallback(NO);
        }
    }
}

#pragma mark ----- public api
-(void) refreshImage {
    // 重置
    [self.captchaView reset];
}

-(void) setImage:(UIImage *)image {
    // 重置
    [self.captchaView reset];
    // 设置背景
    [self.captchaView beginConfiguration];
    self.captchaView.bgImage = image;
    self.captchaView.thumbShape = [UIBezierPath bezierPathWithPathMaker:^(DWPathMaker *maker) {
        maker.MoveTo(0, 16).
        AddLineTo(24, 16).AddArcWithPoint(24, 16, 40, 16, 10, YES, YES).AddLineTo(64, 16).
        AddLineTo(64, 40).AddArcWithPoint(64, 40, 64, 56, 10, YES, YES).AddLineTo(64, 80).
        AddLineTo(40, 80).AddArcWithPoint(40, 80, 24, 80, 10, NO, YES).AddLineTo(0, 80).
        AddLineTo(0, 56).AddArcWithPoint(0, 56, 0, 40, 10, NO, YES).ClosePath();
    }];
    self.captchaView.thumbMinX = 100;
    [self.captchaView commitConfiguration];
    self.dragable = YES;
}

-(void) setImageWithUrl:(NSString *)urlStr {
    self.dragable = NO;
    [self.activityIndicator startAnimating];
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        NSURL *url = [NSURL URLWithString:urlStr];
        NSData *data = [NSData dataWithContentsOfURL:url];
        if (data) {
            NSLog(@"图片下载成功！url=%@，size=%lu", urlStr, (unsigned long)data.length);
            UIImage *image = [UIImage imageWithData:data];
            dispatch_async(dispatch_get_main_queue(), ^{
                [self.activityIndicator stopAnimating];
                [self setImage:image];
            });
        } else {
            NSLog(@"图片下载失败！url=%@", urlStr);
            dispatch_async(dispatch_get_main_queue(), ^{
                [self.activityIndicator stopAnimating];
            });
        }
    });
}


-(void) setHideMode:(SlideView_DisplayHideBlock) callback {
    displayHide = YES;
    self.displayHideCallback = callback;
    [self hideImageWithAnimation:false];
}

- (void) setSliderThumbImage:(UIImage *)sliderThumbImage {
    [self.slider setThumbImage:[sliderThumbImage dw_RescaleImageToTargetHeight:trackHeight] forState:UIControlStateNormal];
}

- (void) setSliderTipText:(NSString *)sliderTipText {
    [self.sliderTextView setText:sliderTipText];
}

- (void) setSliderSuccessText:(NSString *)sliderSuccessText {
    [self.successTextView setText:sliderSuccessText];
}

@end
